<?php
class basketPageActions extends myFrontendAction{
	
	public function preExecute(){
		parent::preExecute();
		$this->setLayout('layout_widgets_off');
	}


	/*
	 * payment step, when user submits his SHIPPING and BILLING information
	 */
	public function executeSubmitAddresses(sfWebRequest $request){

		$forms = array(
			'shipping_address' => new PublicUserAddressForm(),
			'billing_address' => new PublicUserAddressForm()
		);

		$isValid = true;
		$messages = array();
		$status = 200;
		$redirect = '';
		$shortMessage = '';

		// check both forms
		foreach($forms as $index => $form){
			$bindArray = $request->getParameter($index);
			unset($bindArray['id']); // do not need to update. Only check that info is correct
			$form->bind($bindArray);
			if(!$form->isValid()){
				$shortMessage = 'Epic fail';
				$isValid = false;
				$status = 500;

				foreach($form->getErrorSchema() as $field => $msg){
					$messages[$index][$field] = $msg . "";
				}
				
			}
		}
		if($isValid){

			myBasket::getInstance(myBasket::SESSION_BASED)->setShippingAddress($forms['shipping_address']->getValues());
			myBasket::getInstance(myBasket::SESSION_BASED)->setBillingAddress($forms['billing_address']->getValues());

			$redirect  =  
				LinkGen::getInstance(LinkGen::STRUCTURE)->link($this->getRoute()->getObject()->getId(),
					array('step' => 4));
			
		}


		return $this->renderPartial('global/json', array(
			'item' => array(
				'status' => $status,	// 200 on success and 500 on fail
				'redirect' => $redirect, // set only if validation succeeded
				'messages' => $messages,  // errors if validation not succeeded
				'shortMessage' => $shortMessage // success message
			)
		));

	}

  /*
   * Executed when user selects SHIPPING or BILLING address
   * 
   */
  public function executeGetForm(sfWebRequest $request){
	$this->setLayout(false);

	$address = Doctrine::getTable('PublicUserAddresses')->findOneByPublicUserIdAndId(
		$this->getUser()->getObject()->getId(),
		$request->getParameter('address', -1)
	);

	if($address){
		$this->form = new PublicUserAddressForm($address);

	}else{
		switch($request->getParameter('address')){
			case 'shipping':
				$address = new PublicUserShippingAddress();
				$address->fromArray(
					array(
						'public_user_id' => $this->getUser()->getObject()->getId(),
						'type' => 'shipping',
					)
				);
				$this->form = new PublicUserAddressForm($address);
				break;
			case 'billing':
				$address = new PublicUserShippingAddress();
				$address->fromArray(
					array(
						'public_user_id' => $this->getUser()->getObject()->getId(),
						'type' => 'billing',
					)
				);
				$this->form = new PublicUserAddressForm($address);
				break;
		}
	}

	$formHTML = $this->getPartial('basketPage/form', array('form' => $this->form));


	return $this->renderPartial('global/json', array(
		'item' => array(
			'formHTML' => $formHTML
		)
	));

  }
	
	/*
	 * adding product to basket
	 */
	public function executeAddProductToBasket(sfWebRequest $request){
		$this->setLayout(false);
		sfProjectConfiguration::getActive()->loadHelpers(array('I18N'));

		$this->params = array();

		$prod = Doctrine::getTable('Product')->find($request->getParameter('productID'));
		
		if($prod['instock'] <= myBasket::getInstance(myBasket::SESSION_BASED)->getProductAmount($request->getParameter('productID'))){
			$this->params['html'] = $this->getComponent('basketWidget','widget', array('visible' => true) );
			$this->params['message'] = __('Out of stock');
			$this->params['message_short'] = __('out of stock');

			$this->params['code'] = 200;
		}elseif(myBasket::getInstance(myBasket::SESSION_BASED)->addProduct( $request->getParameter('productID'), (int)$request->getParameter('qty',1) )){

			$this->params['html'] = $this->getComponent('basketWidget','widget', array('visible' => true) );
			$this->params['message'] = __('Added. Add more?');
			$this->params['message_short'] = __('Added to basket');
			
			$this->params['code'] = 200;
		}else{
			$this->params['code'] = 500;
			$this->params['message'] = __('error occured');
			$this->params['message_short'] = __('error');
		}
	}

	/*
	 * deleting product from basket
	 */
	public function executeDeleteFromBasket(sfWebRequest $request){
		$this->setLayout(false);
		sfProjectConfiguration::getActive()->loadHelpers(array('Currency'));
		
		myBasket::getInstance(myBasket::SESSION_BASED)->deleteProduct( $request->getParameter('productID') );
		
		$this->redirect($request->getReferer());
	}


	/*
	 * changing amount of product
	 */
	public function executeChangeAmount(sfWebRequest $request){
		$this->setLayout(false);

		myBasket::getInstance()->changeAmount($request->getParameter('productID'), $request->getParameter('qty'));

		$this->params = array();
		$this->params['html'] = $this->getComponent('basketPage','basket', array('visible' => true) );
		$this->params['total'] = price_format(myBasket::getInstance()->getTotalPrice(), $this->getUser() );

		foreach(myBasket::getInstance()->prepareDataForView() as $prod){
			if($prod['product']['id'] == $request->getParameter('productID'))
				$this->params['price'] = price_format($prod['product']['price_actual'] * $prod['quanity'], $this->getUser());
		}

		$this->setTemplate('addProductToBasket');
	}
	
	
	public function executeNextStep(sfWebRequest $request){

		# init variables
		$basket = myBasket::getInstance(myBasket::SESSION_BASED);
		$node = $this->getRoute()->getObject();
		
		# redirect use if he/she is not logged in
		# current referer is passed as REDIRECT param
		if(!$this->getUser()->isAuthenticated()){
			$this->redirect( LinkGen::getInstance(LinkGen::STRUCTURE)->link($node['id'], array('step' => 2, 'redirect' => $request->getReferer())) );
		}

		switch($request->getParameter('step')){
			case 1:
				$redirectLink = LinkGen::getInstance(LinkGen::STRUCTURE)->link($node['id'], array('step' => 3));
				break;
			case 2:
				$redirectLink = LinkGen::getInstance(LinkGen::STRUCTURE)->link($node['id'], array('step' => 3));
				break;
			case 3:
				$redirectLink = LinkGen::getInstance(LinkGen::STRUCTURE)->link($node['id'], array('step' => 4));
			case 4:
				$redirectLink = LinkGen::getInstance(LinkGen::STRUCTURE)->link($node['id'], array('step' => 5));
		}

		$this->redirect($redirectLink);
	}

	public function executeDoCheckout(sfWebRequest $request){

		$basket = myBasket::getInstance(myBasket::SESSION_BASED);
		$node = $this->getRoute()->getObject();

//		# redirect to "order" action
		if(!$this->getUser()->isAuthenticated()){
		//	$this->redirect( LinkGen::getInstance(LinkGen::STRUCTURE)->link($node['id'], array('step' => 2)) );
		}

		# validate request
		if(!$basket->getProducts()) // if basket is empty redirect to referer
			$this->redirect($request->getReferer());

		# checkout
		$order = $basket->checkout();
		$order->setType($request->getParameter('type','seb'));
                //var_dump($order);exit;
		$order->save();

		//print_r($order->toArray());
//		print_r($order->getOrederedItems()->toArray());
//		exit;

		# delete products from basket
//		foreach($basket->getProducts() as $id => $qty)
//			$basket->deleteProduct($id);

		$redirectLink = LinkGen::getInstance(LinkGen::STRUCTURE_ACTIONS)->link(null, array('module' => 'basketPage', 'action' => 'proceedToPayment', 'orderID' => $order['id'])  );
		//echo $redirectLink;
		//exit;
		

		$this->redirect($redirectLink);
	}

	public function executeBasketChanged(sfWebRequest $request){
		$this->setLayout(false);

		foreach($request->getParameter('product') as $id => $qty){
			myBasket::getInstance(myBasket::SESSION_BASED)->changeAmount($id, $qty);
		}

		if(($zoneID = $request->getParameter('zoneID'))){
			   myBasket::getInstance(myBasket::SESSION_BASED)->setShippingZone($zoneID);
		}

   }


	
	
	public function executeChangeShippingZone(sfWebRequest $request){
		sfProjectConfiguration::getActive()->loadHelpers(array('Currency', 'Number'));
		
		$this->forward404Unless($this->getUser()->isMyOrder(
								Doctrine::getTable('ProductOrder')->find($this->getRequestParameter('orderID') ) ) );
		
		$id = $this->getRequestParameter('orderID');
		if($request->getParameter('zoneID') == 0){
			return $this->renderPartial('global/json', array('item' => array('total' => price_format(BasketCheckedOut::getInstance($id)->price(myBasket::TOTAL_NO_SHIPPING)),
				'shipping' => price_format(0))));
		}

		$zone = BasketCheckedOut::getInstance($id)->shippingCost($this->getRequestParameter('zoneID'));
		$total = BasketCheckedOut::getInstance($id)->price(myBasket::TOTAL_NO_SHIPPING) + $zone;
		
		return $this->renderPartial('global/json', array('item' => array('total' => price_format($total), 'shipping' => price_format($zone) )));		
	}
	
	
	public function executeProceedToPayment(sfWebRequest $request){
		$this->setLayout(false);
		$order = Doctrine::getTable('ProductOrder')->find($this->getRequestParameter('orderID'));
		
		//$this->forward404Unless($this->getUser()->isMyOrder($order));
		
		if($order->getPayInCurrency() != $this->getUser()->getCurrency()->getAbbr()){ // set new currency if changed during ORDERING FORM filling
			$order->setPayInCurrency($this->getUser()->getCurrency()->getAbbr());
			$order->save();
		}
		
		$this->html = $order->createHiddenFields(LinkGen::getInstance(LinkGen::STRUCTURE_ACTIONS)->link(null, array('module' => 'basketPage', 'action' => 'verifyPayment', 'orderID' => $order['id']), true));
		$this->link = $order->getBankLink()->urlServer;
	}
	
	public function executeVerifyPayment( sfWebRequest $request ){
		$this->setLayout(false);
		sfProjectConfiguration::getActive()->loadHelpers(array('I18N', 'Variable'));
		
		$this->forward404Unless($this->getUser()->isMyOrder(
								Doctrine::getTable('ProductOrder')->find($this->getRequestParameter('orderID') ) ) );
		
		# getting current banklink object
		$bankLink = CBanklink::getBank( Doctrine::getTable('ProductOrder')->find($request->getParameter('orderID'))->getType() );
		
		
		# handling BANK callback and creating payment
		$payment = $bankLink->HandleCallback();
		
		
		# getting ORDER object
		$order = Doctrine::getTable('ProductOrder')->find( $payment->ixOrder );

		$redirectLink = LinkGen::getInstance(LinkGen::STRUCTURE)->link($this->getRoute()->getObject()->getId(), array('step' => 5, 'orderID' => $order['id']));
		/* if order is still NEW: change status, generate ticket, send e-mail to user, send request to webservice */
		if( $order->getStatus() == ProductOrderTable::STATUS_NEW ){
			//$order->raw_response = $this->logRequestVariables();
			if( $payment && $payment->isSuccessful ){
				
				$order->status = ProductOrderTable::STATUS_PAID;
				$order->save();
				
				# send invoice to mail
				//generate invoice
//				$arguments = array('orderID' => $order['id'] );
//				$options = array('host' => $request->getHost(), 'culture' => $this->getUser()->getCulture());
//				$invoiceGenTask = new sfInvoiceGenerationTask(sfContext::getInstance()->getEventDispatcher(), new sfFormatter());
//				chdir(sfConfig::get('sf_root_dir')); // hack to start task from Action
//				$invoiceGenTask->run($arguments, $options);

			}else{
				$order->status = ProductOrderTable::STATUS_CANCELED;
				$order->save();
			}
		}

		# delete products from basket
		foreach(myBasket::getInstance(myBasket::SESSION_BASED)->getProducts() as $id => $qty)
			myBasket::getInstance(myBasket::SESSION_BASED)->deleteProduct($id);


		
		

		$this->redirect($redirectLink);

	}

	public function executeUserInvoice( $request ){
		$order = Doctrine::getTable('ProductOrder')->find($this->getRequestParameter('orderID') );


		if(!file_exists($order->getInvoiceAbsolutePath('pdf'))){
			// init invoice generation task
			$arguments = array('orderID' => $order['id'] );
			$options = array('host' => $request->getHost(), 'culture' => $this->getUser()->getCulture(), 'application' => 'frontend');

			$invoiceGenTask = new sfInvoiceGenerationTask(sfContext::getInstance()->getEventDispatcher(), new sfFormatter());
			chdir(sfConfig::get('sf_root_dir')); // hack to start task from Action
			$invoiceGenTask->run($arguments, $options);
			
		}

		// We'll be outputting a PDF
		header('Content-type: application/pdf');

		// It will be called
		header('Content-Disposition: attachment; filename="' . $order->getInvoiceFilename('pdf') . '"');

		// The PDF source
		readfile($order->getInvoiceAbsolutePath('pdf'));

		return sfView::NONE;
	}
	
	public function executeRestartOrder($request){
		$this->setLayout(false);
		sfProjectConfiguration::getActive()->loadHelpers(array('I18N'));
		
		foreach(myBasket::getInstance(myBasket::SESSION_BASED)->getProducts() as $id => $qty){
			myBasket::getInstance(myBasket::SESSION_BASED)->deleteProduct($id);
		}
		
		$order = Doctrine::getTable('ProductOrder')->find($request->getParameter('orderID'));
		$this->forward404Unless($this->getUser()->isMyOrder($order));
		
		
		$deleted = array();
		foreach($order->OrederedItems as $item){
			# check if product is still in DB
			if(!Doctrine::getTable('Product')->find($item['product_id'])){
					$deleted[] = $item['name'];
					continue;
			}
			
			myBasket::getInstance(myBasket::SESSION_BASED)->addProduct($item['product_id'], $item['quanity']);
		}
		
		
		if($deleted){
			$this->getUser()->setFlash('basket.error', __('Products %1% are currently out of stock', array('%1%' => strtoupper(implode(', ', $deleted)))));
		}
                $id = Doctrine::getTable('Structure')->findOneBy('parameter', 'basket')->getId();
		$redirectLink = LinkGen::getInstance(LinkGen::STRUCTURE)->link($id, array('step' => 4));
		$this->redirect($redirectLink);
	}
	
}